Skip to content

Regenerate registry API snapshot with organizations, impersonation, migration batches, admin user search, and event health endpoints - #358

Merged
eXamadeus merged 1 commit into
mainfrom
julian/06-23-regenerate_registry_api_snapshot_with_organizations_impersonation_migration_batches_private_facets_and_admin_event-health_endpoints
Jun 23, 2026
Merged

Regenerate registry API snapshot with organizations, impersonation, migration batches, admin user search, and event health endpoints#358
eXamadeus merged 1 commit into
mainfrom
julian/06-23-regenerate_registry_api_snapshot_with_organizations_impersonation_migration_batches_private_facets_and_admin_event-health_endpoints

Conversation

@eXamadeus

@eXamadeus eXamadeus commented Jun 23, 2026

Copy link
Copy Markdown
Member

Why

Regenerates the registry API types and OpenAPI snapshot from the latest upstream spec (2026-06-23T20:50:08.809Z), picking up a significant set of new endpoints and schema changes.

Details

Organizations

  • Full CRUD surface for organizations: create/claim (POST /v0/organizations), list (GET /v0/organizations), get by slug, list/invite/remove members, change member roles, edit profile, and accept/decline invitations.
  • Org claims are rate-limited (1/24h, 5/30d) and may be queued for admin review. The review queue now carries org-claim as a valid queue_type alongside global-facet, and queue items include requested_display_name and requested_slug.
  • owner fields on FacetSummary, VersionMetadata, and ScopeRootResponse are now a discriminated union of { kind: "org", slug } and { kind: "user", username } instead of the previous user-only OwnerRef. The standalone OwnerRef schema is removed.
  • visibility ("private" | "public") is now a required field on FacetSummary and VersionMetadata.

Private facets & caller-relative access

  • Version list, latest-version, metadata, and contents endpoints now describe caller-relative authorization: the highest version the caller may read, with no-store caching for private versions and latest resolutions. The 304 Not Modified responses are removed from the metadata and contents operations.
  • GET /v0/facets/count added, returning an eventually-consistent count of live public facets.

Admin impersonation

  • POST /v0/admin/users/{id}/impersonation validates a target (non-admin only) and returns the metadata the UI needs to drive impersonation via X-Facet-Impersonate-User-Id. No token is minted.
  • DELETE /v0/auth/impersonation is a stateless no-op (204) that signals the client to drop its impersonation state.
  • New error codes: E_IMPERSONATION_FORBIDDEN, E_FORBIDDEN.

Admin user search

  • GET /v0/admin/users performs a bounded username-prefix search and returns email, tier, and suspension status.

Migration batches

  • POST /v0/admin/migrations/batches/latest-once starts a "migrate to latest" batch (dry-run then real-run for each pending migration, in dependency order).
  • GET /v0/admin/migrations/batches/{batchId} polls batch status and progress.
  • POST /v0/admin/migrations/batches/{batchId}/cancel cancels a running batch and force-releases the global migration lease.
  • MigrationBatchResponse schema added; MigrationListResponse gains a latest_batch field.
  • New error codes: E_MIGRATION_BATCH_NOT_FOUND, E_MIGRATION_BATCH_RUNNING.

Event delivery health

  • GET /v0/admin/event-health exposes pending backlog size, oldest-pending age, and the full unresolved dead-letter set.

Other new error codes
E_ALREADY_MEMBER, E_GLOBAL_FACET_MUST_BE_PUBLIC, E_INVITATION_NOT_FOUND, E_MEMBER_NOT_FOUND, E_ORG_FORBIDDEN, E_ORG_LAST_ADMIN, E_ORG_NAME_RESERVED, E_ORG_NAME_TAKEN, E_ORG_NOT_FOUND, E_PRIVATE_FACET_ENTITLEMENT_REQUIRED.

Verification

CI — this is a codegen refresh with no hand-written logic.

Summary by CodeRabbit

  • New Features
    • Added organization ownership and visibility controls for facets and versions.
    • Introduced comprehensive organization management API with creation, listing, member management, and invitation handling.
    • Added public facet count endpoint.
    • New admin capabilities for user management, impersonation, and migration batch orchestration.
    • Added event delivery health monitoring for administrators.

…igration batches, private facets, and admin event-health endpoints
Copilot AI review requested due to automatic review settings June 23, 2026 20:56
@changeset-bot

changeset-bot Bot commented Jun 23, 2026

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: ada314b

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@coderabbitai

coderabbitai Bot commented Jun 23, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The OpenAPI snapshot is regenerated to reflect several contract changes. The standalone OwnerRef schema is removed; FacetSummary, VersionMetadata, and ScopeRootResponse now carry an inline anyOf owner union (org with slug, or user with username) alongside a new visibility enum field. Test fixtures for versionMetadata and facetSummary are updated to include matching owner and visibility defaults.

New schemas include PublicFacetCountResponse, MigrationBatchResponse, AdminUserListResponse, StartImpersonationResponse, EventDeliveryHealthResponse, and org/member schemas. Queue responses gain org-claim as a queue_type value and new requested identity fields. New endpoints span facet count, impersonation start/stop, migration batch orchestration, admin user search, event delivery health, and a full organizations API group. Several facet endpoint descriptions are revised for caller-relative authorization and caching semantics.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main objective of this PR—regenerating the registry API snapshot with multiple major endpoint and schema additions.
Description check ✅ Passed The description comprehensively covers Why, Details, and Verification sections with thorough explanations of organizations, private facets, impersonation, user search, migration batches, event health, and new error codes.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch julian/06-23-regenerate_registry_api_snapshot_with_organizations_impersonation_migration_batches_private_facets_and_admin_event-health_endpoints

Comment @coderabbitai help to get the list of available commands.

Copy link
Copy Markdown
Member Author

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

eXamadeus commented Jun 23, 2026

Copy link
Copy Markdown
Member Author

Merge activity

  • Jun 23, 8:59 PM UTC: A user started a stack merge that includes this pull request via Graphite.
  • Jun 23, 9:20 PM UTC: Graphite couldn't merge this PR because it failed for an unknown reason (GitHub is reporting that this PR is not mergeable, despite passing required status checks defined by your branch protection rules. Please check your rulesets for additional blocking criteria. Graphite Merge Queue does not currently support rulesets. Please contact Graphite support for further assistance.).

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: ada314b264

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +2227 to +2230
summary: Search users by username prefix
description: Bounded username-prefix search over the GSI3
USER_ALL#<first-letter> partition. Admin-gated, so the response carries
email, tier, and suspension status. An empty `q` returns no users.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Declare the user-search query parameter

The new admin user search is described as prefix-based and explicitly mentions q, but the OpenAPI operation does not declare any query parameters, so the generated client type is parameters.query?: never. Any typed caller for this endpoint cannot send ?q=alice; it will hit the empty-query case that the description says returns no users. The organization invite lookup has the same omission, so both user-search surfaces are effectively unusable from the generated client.

Useful? React with 👍 / 👎.

- organizations
security:
- BearerAuth: []
responses:

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Add request bodies for organization mutations

This new POST /v0/organizations operation has no requestBody, which generated requestBody?: never in the typed client. The endpoint description requires the caller to submit at least the organization slug/display data to create or claim an org, so a typed client cannot make a valid request; the same missing-body pattern affects inviting members, changing roles, and editing the profile.

Useful? React with 👍 / 👎.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/engine/src/registry/openapi.snapshot.yaml (1)

1326-1360: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Declare optional authentication on caller-relative facet reads.

Line 1326, Line 1358, Line 1384, and Line 1438 now document caller-relative/private-readable results, but these operations still do not model BearerAuth. Generated clients/docs will not know auth is accepted for resolving private/latest reads.

Contract shape to add upstream before regenerating
 /v0/facets/{name}/latest-version:
   get:
     tags:
       - facets
+    security:
+      - {}
+      - BearerAuth: []

 /v0/facets/{name}/versions/{version}:
   get:
     tags:
       - facets
+    security:
+      - {}
+      - BearerAuth: []

 /v0/facets/{name}/{version}:
   get:
     tags:
       - facets
+    security:
+      - {}
+      - BearerAuth: []

 /v0/facets/{name}/{version}/contents:
   get:
     tags:
       - facets
+    security:
+      - {}
+      - BearerAuth: []

As per coding guidelines, packages/engine/src/registry/openapi.snapshot.yaml is a vendored OpenAPI snapshot with a 4-line header; commit it but never hand-edit it.

Also applies to: 1384-1389, 1438-1440

Source: Coding guidelines


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: e43fc38c-0cdb-4f2b-bdb3-76410a36a5ed

📥 Commits

Reviewing files that changed from the base of the PR and between b9a3f5b and ada314b.

⛔ Files ignored due to path filters (1)
  • packages/engine/src/registry/generated/registry-api.ts is excluded by !**/generated/**
📒 Files selected for processing (2)
  • packages/engine/src/registry/fixtures.ts
  • packages/engine/src/registry/openapi.snapshot.yaml

Comment on lines +2224 to +2253
/v0/admin/users:
get:
operationId: getV0AdminUsers
summary: Search users by username prefix
description: Bounded username-prefix search over the GSI3
USER_ALL#<first-letter> partition. Admin-gated, so the response carries
email, tier, and suspension status. An empty `q` returns no users.
tags:
- admin
security:
- BearerAuth: []
responses:
"200":
description: Matching users
content:
application/json:
schema:
$ref: "#/components/schemas/AdminUserListResponse"
"401":
description: Missing or invalid credentials
content:
application/json:
schema:
$ref: "#/components/schemas/ApiErrorBody"
"403":
description: Caller is not an admin (or caller is suspended)
content:
application/json:
schema:
$ref: "#/components/schemas/ApiErrorBody"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Expose the username-prefix query parameter.

Line 2228 documents admin search by prefix and Line 2542 documents invite lookup by query, but neither operation declares a q query parameter. Typed clients generated from this spec cannot pass the search term without escaping the contract.

Contract shape to add upstream before regenerating
 /v0/admin/users:
   get:
+    parameters:
+      - name: q
+        in: query
+        required: false
+        schema:
+          type: string

 /v0/organizations/{slug}/lookup-user:
   get:
     parameters:
       - schema:
           type: string
         in: path
         name: slug
         required: true
+      - name: q
+        in: query
+        required: false
+        schema:
+          type: string

As per coding guidelines, packages/engine/src/registry/openapi.snapshot.yaml is a vendored OpenAPI snapshot with a 4-line header; commit it but never hand-edit it.

Also applies to: 2538-2572

Source: Coding guidelines

Comment on lines +2464 to +2496
/v0/organizations:
post:
operationId: postV0Organizations
summary: Create or claim an organization
description: Auto-creates the organization when the slug is unprotected and
within the per-user claim budget (1/24h, 5/30d); otherwise queues the
claim for admin review. Reserves the matching @<slug> scope and makes
the caller the founding Admin.
tags:
- organizations
security:
- BearerAuth: []
responses:
"201":
description: Organization created
content:
application/json:
schema:
$ref: "#/components/schemas/OrgDetailResponse"
"202":
description: Claim queued for admin review
"403":
description: Blocked or reserved name
content:
application/json:
schema:
$ref: "#/components/schemas/ApiErrorBody"
"409":
description: Slug taken or a pending claim exists
content:
application/json:
schema:
$ref: "#/components/schemas/ApiErrorBody"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift

Add request bodies for mutating organization endpoints.

Line 2465 creates/claims an org without any slug/display-name input, Line 2607 invites a member without target/role input, Line 2642 changes a role without the new role, and Line 2709 updates a profile without profile fields. Generated clients will model these as empty POSTs.

Contract shape to add upstream before regenerating
 /v0/organizations:
   post:
+    requestBody:
+      required: true
+      content:
+        application/json:
+          schema:
+            $ref: "`#/components/schemas/CreateOrganizationRequest`"

 /v0/organizations/{slug}/members:
   post:
+    requestBody:
+      required: true
+      content:
+        application/json:
+          schema:
+            $ref: "`#/components/schemas/InviteOrgMemberRequest`"

 /v0/organizations/{slug}/members/{userId}/role:
   post:
+    requestBody:
+      required: true
+      content:
+        application/json:
+          schema:
+            $ref: "`#/components/schemas/UpdateOrgMemberRoleRequest`"

 /v0/organizations/{slug}/profile:
   post:
+    requestBody:
+      required: true
+      content:
+        application/json:
+          schema:
+            $ref: "`#/components/schemas/UpdateOrgProfileRequest`"

As per coding guidelines, packages/engine/src/registry/openapi.snapshot.yaml is a vendored OpenAPI snapshot with a 4-line header; commit it but never hand-edit it.

Also applies to: 2606-2634, 2640-2673, 2708-2736

Source: Coding guidelines

@greptile-apps

greptile-apps Bot commented Jun 23, 2026

Copy link
Copy Markdown

Greptile encountered an error while reviewing this PR. Please reach out to support@greptile.com for assistance.

@eXamadeus
eXamadeus merged commit 2ddde92 into main Jun 23, 2026
7 of 8 checks passed
@eXamadeus
eXamadeus deleted the julian/06-23-regenerate_registry_api_snapshot_with_organizations_impersonation_migration_batches_private_facets_and_admin_event-health_endpoints branch June 23, 2026 21:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants